package com.kartoshka.core 
{
	import com.kartoshka.interfaces.IValidatable;
	import com.kartoshka.painters.NullPainter;
	import com.kartoshka.layouts.NullLayout;
	import com.kartoshka.interfaces.IPainter;
	import com.kartoshka.interfaces.ILayout;
	import com.kartoshka.utils.CoreUtil;
	import com.kartoshka.managers.ValidationManager;
	import com.kartoshka.namespaces.pureshka;

	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.display.DisplayObject;
	import flash.display.Sprite;

	/**
	 * @author Alexander Zats, 2009
	 */
	
	use namespace pureshka;

	public class UIBase extends Sprite implements IValidatable 
	{

		//managers references
		protected var _validationManager : ValidationManager = ValidationManager.instance;

		//uid
		private const _uid : String = CoreUtil.getUid( this );

		//main layers
		pureshka var layerChrome : Sprite;
		pureshka var layerContent : Sprite;
		pureshka var layerOverlay : Sprite;

		//overrided width and height 
		protected var _width : Number;
		protected var _height : Number;

		//percent width and height
		protected var _percentWidth : Number;
		protected var _percentHeight : Number;

		//centers
		protected var _horizontalCenter : Number;
		protected var _verticalCenter : Number;
		protected var _horizontalCenterRelative : Number;
		protected var _verticalCenterRelative : Number;

		//percent centers
		protected var _percentVercticalCenter : Number;
		protected var _percentHorizontalCenter : Number;
		protected var _percentHorizontalCenterRelative : Number;
		protected var _percentVerticalCenterRelative : Number;

		//margins
		protected var _marginLeft : Number;
		protected var _marginTop : Number;
		protected var _marginRight : Number;
		protected var _marginBottom : Number;

		//paddings
		protected var _paddingLeft : Number;
		protected var _paddingTop : Number;
		protected var _paddingRight : Number;
		protected var _paddingBottom : Number;

		//layout
		protected var _layout : ILayout;

		//background
		protected var _background : IPainter;

		/*
		 * Differed validation flag
		 * When you call <code>invalidate</code> method you can optionaly specify which validation phase you want to go through.
		 * Until <code>validate</code> method is called all flags passed to <code>invalidate</code> method stored in this variable.
		 * When validation happening, <code>_validationFlags</code> sets to 0.
		 * This way we can ensure  that even if you immideatly call <code>validate</code> method nothing will happends.  
		 */
		protected var _validationFlags : int;

		// DisplayEventListener parameters
		private var displayEventListeners : Array;

		public function UIBase()
		{
			super.addChild( layerChrome = new Sprite( ) );
			super.addChild( layerContent = new Sprite( ) );
			super.addChild( layerOverlay = new Sprite( ) );
			
			layerChrome.addEventListener( MouseEvent.CLICK, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.DOUBLE_CLICK, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_DOWN, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_MOVE, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_OUT, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_OVER, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_UP, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.MOUSE_WHEEL, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.ROLL_OUT, layerChromeMouseEventsTranslator, false, - 1, true );
			layerChrome.addEventListener( MouseEvent.ROLL_OVER, layerChromeMouseEventsTranslator, false, - 1, true );
			
			_layout = new NullLayout( );
			_background = new NullPainter( );
			
			_width = 0;
			_height = 0;
			
			_percentWidth = NaN;
			_percentHeight = NaN;
			
			_marginLeft = NaN;
			_marginTop = NaN;
			_marginRight = NaN;
			_marginBottom = NaN;
			
			_paddingLeft = 0;
			_paddingTop = 0;
			_paddingRight = 0;
			_paddingBottom = 0;
			
			//TODO custom focus should be implemented
			super.focusRect = false;
			
			invalidate( );
			
			displayEventListeners = [];
			addEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
			addEventListener( Event.REMOVED_FROM_STAGE, removedFromStageHandler );
		}

		
		//���������������������������������������������������
		//	Stage depended functions
		//���������������������������������������������������

		private function addedToStageHandler(event : Event) : void 
		{
			if (event.target != this) return;
			var listener : DisplayEventListener;
			for each(listener in displayEventListeners) listener.add( );
		}

		private function removedFromStageHandler(event : Event) : void 
		{
			if (event.target != this) return;
			var listener : DisplayEventListener;
			for each(listener in displayEventListeners) listener.remove( );
		}

		/*
		 * Adding event listener to any DisplayObject instance. Handler can be invoked only when caller of this function is being on stage.
		 * This function can be used in useCapture phase. In this case you need to specify <code>target</code> (an DisplayObject instance
		 * which will be used as EventDisplatcher, parent, stage, etc.) and set <code>useCapture</code> to <code>true</code>.
		 * By default <code>target</code> is <code>null</code> and caller of this function is used as event target.  
		 * */
		public function addDisplayEventListener(type : String, handler : Function, target : DisplayObject = null, useCapture : Boolean = false) : void 
		{
			if (! target) target = this;
			var removableListener : DisplayEventListener = new DisplayEventListener( target, type, handler, useCapture );
			var xRemovableListener : DisplayEventListener;
			for each (xRemovableListener in displayEventListeners) if (DisplayEventListener.compare( xRemovableListener, removableListener )) return;
			displayEventListeners.unshift( removableListener );
			removableListener.add( );
		}

		/*
		 * Removes event listener which was added by <code>addDisplayEventListener</code> function. You can temporary remove event listener by usual <code>removeEventListener</code>
		 * function but it will be added again automatically next time you add instance of this class on stage.
		 */
		public function removeDisplayEventListener(type : String, handler : Function, target : DisplayObject = null, useCapture : Boolean = false) : void 
		{
			if (! target) target = this;
			var removableListener : DisplayEventListener = new DisplayEventListener( target, type, handler, useCapture );
			var xRemovableListener : DisplayEventListener;
			var counter : int = 0;
			for each (xRemovableListener in displayEventListeners) 
			{
				if (DisplayEventListener.compare( xRemovableListener, removableListener )) 
				{
					xRemovableListener.remove( );
					displayEventListeners.splice( xRemovableListener );
					return;
				}
				counter++;
			}
		}

		/*
		 * Prepares instance and its content to be fully collected by garbage collector.
		 * Removes all event listeners which was added by <code>addDisplayEventListener</code> function.
		 */ 
		public function dispose() : void 
		{
			var listener : DisplayEventListener;
			for each(listener in displayEventListeners) listener.remove( );
			displayEventListeners = [];
			removeEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
			removeEventListener( Event.REMOVED_FROM_STAGE, removedFromStageHandler );
		}

		
		//���������������������������������������������������
		//	Validation
		//���������������������������������������������������
		
		/*
		 * Requesting validation in the end of the current frame.
		 * Differed validation also avaiable: if no parameters specified, then validation will go through all phases.
		 * This is equal to <code>ValidationManager.VALIDATE_ALL</code>, also possible values are: <code>ValidationManager.VALIDATE_CHILDRENS</code>, <code>ValidationManager.VALIDATE_INTERNAL_CHILDRENS</code>, <code>ValidationManager.VALIDATE_CHROME</code> and <code>ValidationManager.VALIDATE_STYLE</code>.
		 * If function is called twise betwin validations happened, effect will be appended to previous.
		 * Each time <code>validation</code> function is called, validation flag variable will be set to null, so next time you'll call validation function it'll do nothing.  
		 */
		public function invalidate( flag : int = - 1 ) : void
		{
			_validationFlags |= ( flag == - 1 ) ? ValidationManager.VALIDATE_ALL : flag;
			_validationManager.addToQueue( this );
		}

		public function validate() : void
		{
			if ( ( _validationFlags & ValidationManager.VALIDATE_PARENT ) == ValidationManager.VALIDATE_PARENT )
			{

			}
			if ( ( _validationFlags & ValidationManager.VALIDATE_STYLE ) == ValidationManager.VALIDATE_STYLE ) 
			{
				trace( "\t\tvalidating style" );
				validateStyle( );
			}
			if ( ( _validationFlags & ValidationManager.VALIDATE_INTERNAL_CHILDRENS ) == ValidationManager.VALIDATE_INTERNAL_CHILDRENS ) 
			{
				trace( "\t\tvalidating internal chilrens layout" );
				validateInternalChildren( );
			}
			if ( ( _validationFlags & ValidationManager.VALIDATE_CHILDREN ) == ValidationManager.VALIDATE_CHILDREN ) 
			{
				trace( "\t\tvalidating childrens layout" );
				validateChildren( );
			}
			if ( ( _validationFlags & ValidationManager.VALIDATE_CHROME ) == ValidationManager.VALIDATE_CHROME ) 
			{
				trace( "\t\tvalidating chrome" ); 
				validateChrome( );
			}
			_validationFlags = 0;
		}

		pureshka function validateStyle() : void
		{
		}

		pureshka function validateInternalChildren() : void
		{
			_layout.placeChildrens( _width, _height, layerChrome, true, _paddingLeft, _paddingTop, _paddingRight, _paddingBottom );
		}

		pureshka function validateChildren() : void
		{
			_layout.placeChildrens( _width, _height, layerContent, true, _paddingLeft, _paddingTop, _paddingRight, _paddingBottom );
		}

		pureshka function validateChrome() : void
		{
			layerChrome.graphics.clear( );
			_background.draw( layerChrome.graphics, _width, _height );
		}

		
		//���������������������������������������������������
		//	Measurements
		//���������������������������������������������������

		public function setSize( width : Number = NaN, height : Number = NaN ) : void
		{
			var isInvalidateNeeded : Boolean = false;
			
			if ( ! isNaN( width ) && width != _width )
			{
				_width = width;
				_percentWidth = NaN;
				isInvalidateNeeded = true;
			}
			if ( ! isNaN( height ) && height != _height )
			{
				_height = height;
				_percentHeight = NaN;
				isInvalidateNeeded = true;
			}
			
			if ( isInvalidateNeeded )
			{
				invalidate( ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
				trace( "resining width and height", _uid );
				this.dispatchEvent( new Event( Event.RESIZE ) );
			}
		}

		override public function set width( value : Number ) : void
		{
			if ( value == _width ) return;
			
			_width = value;
			_percentWidth = NaN;
			invalidate( ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
			trace( "resining width", _uid );
			this.dispatchEvent( new Event( Event.RESIZE ) );
		}

		override public function get width() : Number
		{
			return _width;
		}

		override public function set height( value : Number ) : void
		{
			if ( value == _height ) return;
			
			_height = value;
			_percentHeight = NaN;
			invalidate( ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
			trace( "resizing height", _uid );
			this.dispatchEvent( new Event( Event.RESIZE ) );
		}

		override public function get height() : Number
		{
			return _height;
		}

		public function set percentWidth( value : Number ) : void
		{
			if ( value == _percentWidth ) return;
			
			_percentWidth = value;
			
			invalidate( ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
			
			this.dispatchEvent( new Event( Event.RESIZE ) );
		}

		public function get percentWidth() : Number
		{
			return _percentWidth;
		}

		public function set percentHeight( value : Number ) : void
		{
			if ( value == _percentHeight ) return;
			
			_percentHeight = value;
			invalidate( ValidationManager.VALIDATE_PARENT | ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
			
			this.dispatchEvent( new Event( Event.RESIZE ) );
		}

		public function get percentHeight() : Number
		{
			return _percentHeight;
		}

		public function setMargins( left : Number = NaN, top : Number = NaN, right : Number = NaN, bottom : Number = NaN ) : void
		{
			var isInvalidateNeeded : Boolean = false;
			
			if ( ! isNaN( left ) && left != _marginLeft ) 
			{
				isInvalidateNeeded = true;
				_marginLeft = left;
			}
			if ( ! isNaN( top ) && top != _marginTop )
			{
				isInvalidateNeeded = true;
				_marginTop = top;
			}
			if ( ! isNaN( right ) && right != _marginRight )
			{
				isInvalidateNeeded = true;
				_marginRight = right;
			}
			if ( ! isNaN( bottom ) && bottom != _marginBottom ) 
			{
				isInvalidateNeeded = true;
				_marginBottom = bottom;
			}
			
			if ( isInvalidateNeeded ) dispatchEvent( new Event( Event.RESIZE ) );
		}

		public function set marginLeft( value : Number ) : void
		{
			_marginLeft = value;
			if ( ! isNaN( value ) ) 
			{
				_percentWidth = _horizontalCenter = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT | ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get marginLeft() : Number
		{
			return _marginLeft;
		}

		public function set marginTop( value : Number ) : void
		{
			_marginTop = value;
			if ( ! isNaN( value ) )
			{
				_verticalCenter = _percentHeight = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT | ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get marginTop() : Number
		{
			return _marginTop;
		}

		public function set marginRight( value : Number ) : void
		{
			_marginRight = value;
			if ( ! isNaN( value ) ) 
			{
				_horizontalCenter = _percentWidth = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT | ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get marginRight() : Number
		{
			return _marginRight;
		}

		public function set marginBottom( value : Number ) : void
		{
			_marginBottom = value;
			if ( isNaN( value ) )
			{
				_verticalCenter = _percentHeight = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT | ValidationManager.VALIDATE_CHROME | ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get marginBottom() : Number
		{
			return _marginBottom;
		}

		public function set verticalCenter( value : Number ) : void
		{
			_verticalCenter = value;
			if ( ! isNaN( value ) ) 
			{
				_marginTop = _marginBottom = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT );
		}

		public function get verticalCenter() : Number
		{
			return _verticalCenter;
		}

		public function set horizontalCenter( value : Number ) : void
		{
			_horizontalCenter = value;
			if ( ! isNaN( value ) ) 
			{
				_marginLeft = _marginRight = NaN;
			}
			invalidate( ValidationManager.VALIDATE_PARENT );
		}

		public function get horizontalCenter() : Number
		{
			return _horizontalCenter;
		}

		public function set horizontalCenterRelative( value : Number ) : void
		{
			_horizontalCenterRelative = value;
		}

		public function get horizontalCenterRelative() : Number
		{
			return _horizontalCenterRelative;
		}

		public function set verticalCenterRelative( value : Number ) : void
		{
			_verticalCenterRelative = value;
		}

		public function get verticalCenterRelative() : Number
		{
			return _verticalCenterRelative;
		}

		public function set percentVercticalCenter( value : Number ) : void
		{
			_percentVercticalCenter = value;
		}

		public function get percentVercticalCenter() : Number
		{
			return _percentVercticalCenter;
		}

		public function set percentHorizontalCenter( value : Number ) : void
		{
			_percentHorizontalCenter = value;
		}

		public function get percentHorizontalCenter() : Number
		{
			return _percentHorizontalCenter;
		}

		public function set percentHorizontalCenterRelative( value : Number ) : void
		{
			_percentHorizontalCenterRelative = value;
		}

		public function get percentHorizontalCenterRelative() : Number
		{
			return _percentHorizontalCenterRelative;
		}

		public function set percentVerticalCenterRelative( value : Number ) : void
		{
			_percentVerticalCenterRelative = value;
		}

		public function get percentVerticalCenterRelative() : Number
		{
			return _percentVerticalCenterRelative;
		}

		public function setPaddings( left : Number = NaN, top : Number = NaN, right : Number = NaN, bottom : Number = NaN ) : void
		{
			var isInvalidateNeeded : Boolean = false;
			
			if ( ! isNaN( left ) && left != _paddingLeft ) 
			{
				isInvalidateNeeded = true;
				_paddingLeft = left;
			}
			if ( ! isNaN( top ) && top != _paddingTop )
			{
				isInvalidateNeeded = true;
				_paddingTop = top;
			}
			if ( ! isNaN( right ) && right != _paddingRight )
			{
				isInvalidateNeeded = true;
				_paddingRight = right;
			}
			if ( ! isNaN( bottom ) && bottom != _paddingRight ) 
			{
				isInvalidateNeeded = true;
				_paddingBottom = bottom;
			}
			if ( isInvalidateNeeded ) invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function set paddingLeft( value : Number ) : void
		{
			_paddingLeft = value;
			invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get paddingLeft() : Number
		{
			return _paddingLeft;
		}

		public function set paddingTop( value : Number ) : void
		{
			_paddingTop = value;
			invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get paddingTop() : Number
		{
			return _paddingTop;
		}

		public function set paddingRight( value : Number ) : void
		{
			_paddingRight = value;
			invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get paddingRight() : Number
		{
			return _paddingRight;
		}

		
		public function set paddingBottom( value : Number ) : void
		{
			_paddingBottom = value;
			invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		public function get paddingBottom() : Number
		{
			return _paddingBottom;
		}

		//���������������������������������������������������
		//	Layout
		//���������������������������������������������������

		public function get layout() : ILayout
		{
			return _layout;
		}

		public function set layout( value : ILayout ) : void
		{
			_layout = value;
			invalidate( ValidationManager.VALIDATE_CHILDREN | ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
		}

		//���������������������������������������������������
		//	Background
		//���������������������������������������������������

		public function get background() : IPainter
		{
			return _background;
		}

		public function set background(value : IPainter) : void
		{
			_background = value;
			invalidate( ValidationManager.VALIDATE_CHROME );
		}

		
		//���������������������������������������������������
		//	Native measurments
		//���������������������������������������������������

		pureshka function set width( value : Number ) : void
		{
			super.width = value;
		}

		pureshka function get width() : Number
		{
			return super.width;
		}

		pureshka function set height( value : Number ) : void
		{
			super.height = value;
		}

		pureshka function get height() : Number
		{
			return super.height;
		}

		
		//���������������������������������������������������
		//	Events
		//���������������������������������������������������

		override public function addEventListener(type : String, listener : Function, useCapture : Boolean = false, priority : int = 0, useWeakReference : Boolean = true ) : void
		{
			super.addEventListener( type, listener, useCapture, priority, useWeakReference );
		}

		
		//���������������������������������������������������
		//	Childs access block
		//���������������������������������������������������

		override public function addChild(child : DisplayObject) : DisplayObject
		{
			var answer : DisplayObject = layerContent.addChild( child );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
			if ( answer is UIBase )
			{
				answer.addEventListener( Event.RESIZE, onChildrenResize, false, 0, true ); 
			}
			return answer;
		}

		override public function addChildAt(child : DisplayObject, index : int) : DisplayObject
		{
			var answer : DisplayObject = layerContent.addChildAt( child, index );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
			if ( answer is UIBase )
			{
				answer.addEventListener( Event.RESIZE, onChildrenResize, false, 0, true ); 
			}
			return answer;
		}

		override public function contains(child : DisplayObject) : Boolean
		{
			return layerContent.contains( child );
		}

		override public function getChildAt(index : int) : DisplayObject
		{
			return layerContent.getChildAt( index );
		}

		override public function getChildByName(name : String) : DisplayObject
		{
			return layerContent.getChildByName( name );
		}

		override public function getChildIndex(child : DisplayObject) : int
		{
			return layerContent.getChildIndex( child );
		}

		override public function get numChildren() : int
		{
			return layerContent.numChildren;
		}

		override public function removeChild(child : DisplayObject) : DisplayObject
		{
			var answer : DisplayObject = layerContent.removeChild( child );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
			return answer;
		}

		override public function removeChildAt(index : int) : DisplayObject
		{
			var answer : DisplayObject = layerContent.removeChildAt( index );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
			return answer;
		}

		override public function setChildIndex(child : DisplayObject, index : int) : void
		{
			layerContent.setChildIndex( child, index );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
		}

		override public function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : void
		{
			layerContent.swapChildren( child1, child2 );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
		}

		override public function swapChildrenAt(index1 : int, index2 : int) : void
		{
			layerContent.swapChildrenAt( index1, index2 );
			invalidate( ValidationManager.VALIDATE_CHILDREN );
		}

		
		//���������������������������������������������������
		//	Native childs access block
		//���������������������������������������������������

		pureshka function addChild(child : DisplayObject) : DisplayObject
		{
			return super.addChild( child );
		}

		pureshka function addChildAt(child : DisplayObject, index : int) : DisplayObject
		{
			return super.addChildAt( child, index );
		}

		pureshka function contains(child : DisplayObject) : Boolean
		{
			return super.contains( child );
		}

		pureshka function getChildAt(index : int) : DisplayObject
		{
			return super.getChildAt( index );
		}

		pureshka function getChildByName(name : String) : DisplayObject
		{
			return super.getChildByName( name );
		}

		pureshka function getChildIndex(child : DisplayObject) : int
		{
			return super.getChildIndex( child );
		}

		pureshka function get numChildren() : int
		{
			return super.numChildren;
		}

		pureshka function removeChild(child : DisplayObject) : DisplayObject
		{
			return super.removeChild( child );
		}

		pureshka function removeChildAt(index : int) : DisplayObject
		{
			return super.removeChildAt( index );
		}

		pureshka function setChildIndex(child : DisplayObject, index : int) : void
		{
			super.setChildIndex( child, index );
		}

		pureshka function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : void
		{
			super.swapChildren( child1, child2 );
		}

		pureshka function swapChildrenAt(index1 : int, index2 : int) : void
		{
			super.swapChildrenAt( index1, index2 );
		}

		
		//���������������������������������������������������
		//	Event handlers
		//���������������������������������������������������
		
		/*
		 * @private
		 * Let's translate all <code>layerChrome</code> events as if they are <code>this</code> events
		 */
		private function layerChromeMouseEventsTranslator(event : MouseEvent) : void
		{
			event.stopImmediatePropagation( );
			event.preventDefault( );
			
			this.dispatchEvent( event );
		}

		private function onChildrenResize( event : Event ) : void
		{
			var target : DisplayObject = event.target as DisplayObject;

			if ( target.parent == layerChrome )
			{
				invalidate( ValidationManager.VALIDATE_INTERNAL_CHILDRENS );
			}
			else
			{
				invalidate( ValidationManager.VALIDATE_CHILDREN );
			}
		}

		//���������������������������������������������������
		//	Stuff
		//���������������������������������������������������

		final public function get uid() : String
		{
			return _uid;
		}
	}
}
